package com.paradogs.demo.gate.controller;

import com.paradogs.demo.gate.misc.PlayerOnlineHolder;
import com.paradogs.demo.gate.rpc.LogicClient;
import com.paradogs.framework.common.pojo.cg.CGGateLogin;
import com.paradogs.framework.common.pojo.cg.CGPrepareLogin;
import com.paradogs.framework.common.pojo.misc.LongWrapper;
import com.paradogs.framework.core.annoations.request.PRController;
import com.paradogs.framework.core.annoations.request.PRMsgMapping;
import com.paradogs.framework.core.msg.GCAck;
import com.paradogs.framework.core.msg.PRMsgContextHolder;
import com.paradogs.framework.core.msg.R;
import com.paradogs.framework.core.utils.MsgUtils;
import com.paradogs.framework.gate.GateChannelHolder;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @author: yumi
 * @date: 2023/11/13  14:51
 * @Description: TODO
 */
@Slf4j
@PRController
public class GateController {

    @Autowired
    private LogicClient logicClient;

    @Autowired
    private PlayerOnlineHolder playerOnlineHolder;

    /**
     * 玩家准备从登录服转移连接到网关服，待优化：这里要防止玩家调用
     * @param msg
     */
    @PRMsgMapping("prepareLogin")
    public GCAck prepareLogin(CGPrepareLogin msg) {
        playerOnlineHolder.willLogin(msg.getUid(), msg.getToken());
        return GCAck.success();
    }

    /**
     * 玩家携带 token 登录
     * @param msg
     * @return
     */
    @PRMsgMapping(value = "login", async = true)
    public GCAck login(CGGateLogin msg) {
        PlayerOnlineHolder.WillLoginInfo info = playerOnlineHolder.get(msg.getToken());
        if (info != null) {
            // 绑定 Channel 所属玩家信息，待优化：登录功能可以放在 gate-starter 模块里
            GateChannelHolder.bindSession(PRMsgContextHolder.getChannel(), new GateChannelHolder.Session(info.getUid()));
            logicClient.loadPlayer(new LongWrapper(info.getUid()));
            playerOnlineHolder.removeToken(msg.getToken());
            return GCAck.success();
        }
        return GCAck.fail();
    }

    /**
     * 同步玩家自身数据
     */
    @PRMsgMapping("syncData")
    public void syncData(R syncData) {
        Channel channel = GateChannelHolder.getPlayerChannel(syncData.getPlayerId());
        if (channel != null) {
            MsgUtils.send("syncData", syncData, channel);
        }
    }

}
